﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace KentekenHerkenning
{
    class LicensePlateRecognition
    {
        public static Bitmap startAlgo1(Bitmap input)
        {

            #region localisation
            //localisation here

            Bitmap mhhs = MeanHSVAlgorithm.DoAlgorithm(input);
            bool equal = true; //equal houd bij of er equalisatie is uitgevoerd op het plaatje
            Bitmap equalized;
            
            if (MeanHSVAlgorithm.Hue < 130.0 || MeanHSVAlgorithm.Saturation < 0.21) // Als het plaatje donker is.
            {
                EqualisationAlgorithm eq = new EqualisationAlgorithm();
                equal = false;
                equalized = EqualisationAlgorithm.DoAlgorithm(input); // voert equalisation op plaatje uit om hem lichter te maken
            }
            else // als het plaatje licht is equalizatie niet nodig
            {
                equalized = input;
            }

            LocateLicensePlate loc = new LocateLicensePlate();
            Bitmap returnImage = loc.DoAlgorithm(equalized);
            int Height = returnImage.Height;
            int Width = returnImage.Width;
            int size = Width * Height;

            if (Height * 2 > Width || size < 50) //Kijkt of een mogelijk nummerbord is gevonden
            // height/width is verhouding van nummerbord, als het plaatje onder de 50 pixels heeft kan er nooit ocr op toegepast worden
            {
                if (equal) // Als er geen mogelijk nummerbord is gevonden kijkt hij of er voorgaand equalisation is gebruikt.
                { //Equalisation word toegepast als deze voorheen niet was toegepast
                    equalized = EqualisationAlgorithm.DoAlgorithm(input);
                }
                else if (!equal) // als er wel equalisation was gebruikt dan probeert hij nog een keer het nummerbord te
                { //lokalizeren zonder equalisatie
                    equalized = input;
                }
                returnImage = loc.DoAlgorithm(equalized); //voert het locate algoritme weer uit
            }
            
           
            #endregion
            Console.WriteLine("Done localisation");

            #region lightning
            //lightning here
            LightingAlgorithm LA = new LightingAlgorithm();
            returnImage = LA.DoLighting(returnImage);

            #endregion
            Console.WriteLine("Done Lightning adjustments");

       /*     #region rotation
            //rotation here

            returnImage = RotatePlate.run(returnImage);


            #endregion
            Console.WriteLine("Done rotation adjustments"); */

            #region segmentation
            //segmentation here

            List<Blob> blobbers = new List<Blob>();
            List<Bitmap> Characterlist = new List<Bitmap>();

            blobbers = BlobDetection.doAlgorithm(returnImage);
            int resultCounter = 0;

            blobbers.Sort((x, y) => x.minx.CompareTo(y.minx));

            int pixels = returnImage.Width * returnImage.Height;

            foreach (Blob b in blobbers)
            {
                if (b.amountOfPixels < pixels / 1150)
                    continue;
                if (b.maxx - b.minx < 10)
                    continue;
                if (!(Math.Abs(b.maxx - b.minx) > Math.Abs(b.maxy - b.miny)))
                {
                    PixelPoint tempx = new PixelPoint(b.minx, b.miny, 231, 0, 0, 0, null);
                    PixelPoint tempy = new PixelPoint(b.maxx, b.maxy, 231, 0, 0, 0, null);


                  //  SrcPictureBox.Image = DrawRectangles.drawRectangle((Bitmap)returnImage.Image, tempx, tempy);

                    try
                    {
                        Bitmap temp = (returnImage).crop(b.minx, b.maxx, b.miny, b.maxy);
                       // Characterlist.Add(temp);
                        temp.Save("D://bitmapTestSetCharacters/kek" + resultCounter + ".bmp");

                    }
                    catch (Exception)
                    {
                        Console.WriteLine("Alles gaat hier goed hoor *whistle whistle*");
                    }
                    resultCounter++;
                }
            }

            if (Characterlist.Count == 0)
            {

                foreach (Blob b in blobbers)
                {
                    if (b.amountOfPixels < pixels / 2500)
                        continue;
                    if (b.maxx - b.minx < 10)
                        continue;
                    if (!(Math.Abs(b.maxx - b.minx) > Math.Abs(b.maxy - b.miny)))
                    {
                        PixelPoint tempx = new PixelPoint(b.minx, b.miny, 231, 0, 0, 0, null);
                        PixelPoint tempy = new PixelPoint(b.maxx, b.maxy, 231, 0, 0, 0, null);

                        

                        try
                        {
                            Bitmap temp = (returnImage).crop(b.minx, b.maxx, b.miny, b.maxy);
                            Characterlist.Add(temp);
                            temp.Save("D://bitmapTestSetCharacters/kek" + resultCounter + ".bmp");

                        }
                        catch (Exception)
                        {
                            Console.WriteLine("Alles gaat hier goed hoor *whistle whistle*");
                        }
                        returnImage = DrawRectangles.drawRectangle(returnImage, tempx, tempy);
                        resultCounter++;
                    }
                }

            }


            #endregion
            Console.WriteLine("Done segmentation aantal chars op de plate: " + Characterlist.Count);

            #region OCR
            //OCR here
            List<TestsetCharacter> testSet = null;

            try
            {
                testSet = (List<TestsetCharacter>)testSet.FileToObject("CompareSet.OCR");
                Console.WriteLine("Read succesvol " + testSet.Count + " letters ingelezen");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Read gefaald::::::\n" + ex);
            }

            if (testSet != null)
            {

                List<Char> LPList = new List<char>();
                foreach (Bitmap b in Characterlist)
                {
                    List<TestsetCharacter> finalSet = Awesome_O_CR.doAlgorithm(b, "xxx_%@#76", testSet);

                    if (finalSet.Count == 0)
                    {
                        LPList.Add('?');
                    }
                    else
                    {
                        LPList.Add(Convert.ToChar(finalSet[0].Character));
                    }

                }
                //   sw.Stop();
                try
                {

                    string s = "" + LPList[0];
                    s += LPList[1];
                    s += "-" + LPList[2];
                    s += LPList[3];
                    if (Char.IsNumber(LPList[5]) != Char.IsNumber(LPList[4]))
                    {
                        s += LPList[4] + "-";
                    }
                    else
                    {
                        s += "-" + LPList[4];
                    }

                    s += LPList[5];

                    Console.WriteLine("Het gevonden kenteken is : " + s);
                    // Console.WriteLine("Tijd: " + (sw.ElapsedMilliseconds - i)); // start+stop time from stopwatch is substracted

                    s = "";
                }
                catch
                {
                    Console.WriteLine("Dit kenteken is te lelijk om een fatsoenlijk kenteken uit te halen..");
                    Console.WriteLine("Dit is natuurlijk de fout van andere groepen.");
                    Console.WriteLine("Persoonlijk denken wij dat de rotatie en vervorming groep dit fout gedaan hebben.");



                }
            }

            blobbers.Clear();
            Characterlist.Clear();
            GC.Collect();

            #endregion
            Console.WriteLine("Done OCR");

            GC.Collect();

            return returnImage;
        }

        public static Bitmap startAlgo2(Bitmap input)
        {

            #region localisation
            //localisation here

            Bitmap mhhs = MeanHSVAlgorithm.DoAlgorithm(input);
            bool equal = true; //equal houd bij of er equalisatie is uitgevoerd op het plaatje
            Bitmap equalized;

            if (MeanHSVAlgorithm.Hue < 130.0 || MeanHSVAlgorithm.Saturation < 0.21) // Als het plaatje donker is.
            {
                EqualisationAlgorithm eq = new EqualisationAlgorithm();
                equal = false;
                equalized = EqualisationAlgorithm.DoAlgorithm(input); // voert equalisation op plaatje uit om hem lichter te maken
            }
            else // als het plaatje licht is equalizatie niet nodig
            {
                equalized = input;
            }

            LocateLicensePlate loc = new LocateLicensePlate();
            Bitmap returnImage = loc.DoAlgorithm(equalized);
            int Height = returnImage.Height;
            int Width = returnImage.Width;
            int size = Width * Height;

            if (Height * 2 > Width || size < 50) //Kijkt of een mogelijk nummerbord is gevonden
            // height/width is verhouding van nummerbord, als het plaatje onder de 50 pixels heeft kan er nooit ocr op toegepast worden
            {
                if (equal) // Als er geen mogelijk nummerbord is gevonden kijkt hij of er voorgaand equalisation is gebruikt.
                { //Equalisation word toegepast als deze voorheen niet was toegepast
                    equalized = EqualisationAlgorithm.DoAlgorithm(input);
                }
                else if (!equal) // als er wel equalisation was gebruikt dan probeert hij nog een keer het nummerbord te
                { //lokalizeren zonder equalisatie
                    equalized = input;
                }
                returnImage = loc.DoAlgorithm(equalized); //voert het locate algoritme weer uit
            }


            #endregion
            Console.WriteLine("Done localisation");

            #region lightning
            //lightning here
            LightingAlgorithm LA = new LightingAlgorithm();
            returnImage = LA.DoLighting(returnImage);

            #endregion
            Console.WriteLine("Done Lightning adjustments");

            #region rotation
            //rotation here

            //returnImage = RotatePlate.run(returnImage);


            #endregion
            Console.WriteLine("Done rotation adjustments");

            #region segmentation
            //segmentation here

            List<Blob> blobbers = new List<Blob>();
            List<Bitmap> Characterlist = new List<Bitmap>();

            blobbers = BlobDetection.doAlgorithm(returnImage);
            int resultCounter = 0;

            blobbers.Sort((x, y) => x.minx.CompareTo(y.minx));

            int pixels = returnImage.Width * returnImage.Height;


            foreach (Blob b in blobbers)
            {
                if (b.amountOfPixels < pixels / 2500)
                    continue;

                if (b.maxx - b.minx < 5)
                    continue;

                if (b.minx <= 10)
                    continue;

                if (((b.maxy - b.miny) / 1.2) < (b.maxx - b.minx))
                    continue;

                if (!(Math.Abs(b.maxx - b.minx) > Math.Abs(b.maxy - b.miny)))
                {
                    PixelPoint tempx = new PixelPoint(b.minx, b.miny, 231, 0, 0, 0, null);
                    PixelPoint tempy = new PixelPoint(b.maxx, b.maxy, 231, 0, 0, 0, null);


                    //  SrcPictureBox.Image = DrawRectangles.drawRectangle((Bitmap)returnImage.Image, tempx, tempy);

                    try
                    {
                        Bitmap temp = (returnImage).crop(b.minx, b.maxx, b.miny, b.maxy);
                        // Characterlist.Add(temp);
                        temp.Save("D://bitmapTestSetCharacters/kek" + resultCounter + ".bmp");

                    }
                    catch (Exception)
                    {
                        Console.WriteLine("Alles gaat hier goed hoor *whistle whistle*");
                    }
                    resultCounter++;
                }
            }

            if (Characterlist.Count == 0)
            {

                foreach (Blob b in blobbers)
                {
                    if (b.amountOfPixels < pixels / 1150)
                        continue;

                    if (b.maxx - b.minx < 5)
                        continue;

                    if (b.minx <= 10)
                        continue;

                    if (((b.maxy - b.miny) / 1.2) < (b.maxx - b.minx))
                        continue;

                    if (!(Math.Abs(b.maxx - b.minx) > Math.Abs(b.maxy - b.miny)))
                    {
                        PixelPoint tempx = new PixelPoint(b.minx, b.miny, 231, 0, 0, 0, null);
                        PixelPoint tempy = new PixelPoint(b.maxx, b.maxy, 231, 0, 0, 0, null);



                        try
                        {
                            Bitmap temp = (returnImage).crop(b.minx, b.maxx, b.miny, b.maxy);
                            Characterlist.Add(temp);
                            temp.Save("D://bitmapTestSetCharacters/kek" + resultCounter + ".bmp");

                        }
                        catch (Exception)
                        {
                            Console.WriteLine("Alles gaat hier goed hoor *whistle whistle*");
                        }
                        returnImage = DrawRectangles.drawRectangle(returnImage, tempx, tempy);
                        resultCounter++;
                    }
                }

            }


            #endregion
            Console.WriteLine("Done segmentation aantal chars op de plate: " + Characterlist.Count);

            #region OCR
            //OCR here
            
            //returns per char list met doubles ( waardes voor meest likely char )

            //geef in een for loop chars mee, kijk naar hoogste waarde en gooi ze door de functie van dylan

            List<Char> LPList = new List<char>();

                foreach (Bitmap b in Characterlist)
                {
                    //Do algortime
                    //Haal hoogste eruit
                    //convert hem naar char

                    //LPList.Add(Convert.ToChar(finalSet[0].Character));
                    double[] temp = new double[36];

                    temp = OCR.DoOCR(b);

                    int highestIndex = 0;
                    double highestDouble = 0;

                    for (int i = 0; i < temp.Length; i++)
                    {
                        if (temp[i] > highestDouble)
                        {
                            highestIndex = i;
                            highestDouble = temp[i];
                        }
                    }

                    //Console.WriteLine(OCR.indexToCharacter(highestIndex) + " " + temp[highestIndex] + "\n");
                    LPList.Add(OCR.indexToCharacter(highestIndex));
                }
                try
                {

                    string s = "" + LPList[0];
                    s += LPList[1];
                    s += "-" + LPList[2];
                    s += LPList[3];
                    if (Char.IsNumber(LPList[5]) != Char.IsNumber(LPList[4]))
                    {
                        s += LPList[4] + "-";
                    }
                    else
                    {
                        s += "-" + LPList[4];
                    }

                    s += LPList[5];

                    Console.WriteLine("Het gevonden kenteken is : " + s);
                    s = "";
                }
                catch
                {
                    Console.WriteLine("Iets en dingen");
                }

            Characterlist.Clear();
            GC.Collect();

            #endregion
            Console.WriteLine("Done OCR");

            GC.Collect();

            return returnImage;
        }

    }
}
